#ifndef _API_DAC_H_
#define _API_DAC_H_

#define PA1_ANL_SET          0x40
#define PA2_ANL_SET          0x80

void dac_cb_init(u16 dac_cfg);
void dac_set_volume(u8 vol);
void dac_set_dvol(u16 vol);
void dac_fade_process(void);
void dac_fade_out(void);
void dac_fade_in(void);
void dac_fade_wait(void);
void dac_analog_fade_in(void);
void dac_set_analog_vol(u16 vol);
void dac_digital_enable(void);
void dac_digital_disable(void);
void dac_spr_set(uint spr);
u8 dac_spr_get(void);
void dac_obuf_init(void);
void dac_src1_init(void);
void dac_power_on(void);
void dac_restart(void);
void dac_power_off(void);
void dac_mono_init(bool dual_en, bool lr_sel);  //lr_sel = true, 表示左声道
void adpll_init(u8 out_spr);
void adpll_spr_set(u8 out48k_flag);
void obuf_put_one_sample(u32 left, u32 right);
void obuf_put_samples(void *buf, uint len);
void dac_unmute_set_delay(u16 delay);
u16 dac_pcm_pow_calc(void);
void dac_channel_enable(void);
void dac_channel_disable(void);
void dac_set_balance(u16 l_vol, u16 r_vol);
void dac_set_balance_lr_switch(u16 l_vol, u16 r_vol);   //调音量平衡时，顺便反一下左右声道
void dac_vbs_init(void *cfg);
void dac_vbs_exit(void);
void dac_high_impedance(u8 enable);
void dac_channel_exchange(void);    //L与R对换
void dac_digital_lr_switch(bool en);  //dac 左右声道数字互换 //en = 1, 启动互换  //en = 0，关闭互换
void dac_dual_vcmbuf_dual_exchange(u8 dac_sel);//dual exchange dual vcmbuf，传参“DAC_CH_SEL”
void dac_fade_sta_set(u32 sta);
void dac_switch_for_bt(u8 enable);
void dac_diff_mono_vcmbuf_dual_exchange(u8 dac_ch_sel);
void dac_src1_set_ch_mix(bool dual_en, bool mix_en, bool left_only);
u16 dnr_voice_maxpow(u32 *ptr, u16 len);  //com code
//drc
void dac_drc_init(void *cfg);
void dac_drc_exit(void);
void drc_set_param(const u32 *tbl);
void dac_drc_set_param_by_res(void *coef, u32 *addr, u32 *len);

//EQ
struct eq_coef_tbl_t {
    const int * coef_0;            //tbl_alpha
    const int * coef_1;            //tbl_cos_w0
};

void music_set_eq_by_res(u32 *addr, u32 *len);
void music_set_soft_eq_by_res(u32 *addr, u32 *len);
void music_set_soft_eq_dual_by_res(u8 lr,u32 *addr, u32 *len);
void music_set_eq_by_num(u8 num);
void music_eq_off(void);
void music_set_eq(u8 band_cnt, const u32 *eq_param);
void music_set_eq_gain(u32 gain);   //32768 (0DB)
bool music_set_eq_is_done(void);    //判断上一次设置EQ是否完成

void mic_set_eq(u8 band_cnt, const u32 *eq_param);
void mic_set_eq_by_res(u32 *addr, u32 *len);   //注意MIC_EQ只支持6段,大于6段设置会无效
void mic_set_eq_gain(u32 gain);
bool mic_set_eq_is_done(void);      //判断上一次设置EQ是否完成

void bass_treble_coef_cal(int *coef, int gain, int mode);                   //gain:-12dB~12dB, mode:0(bass), 1(treble)  //bass/treb频率由bass_treble_get_coef_tbl回调给出。
void bass_treble_coef_cal_freq(int *coef, int gain, int mode, void* freq_coef);  //gain:-12dB~12dB, mode:0(bass), 1(treble)  //bass/treb频率由freq_coef决定
void bass_treble_coef_cal_ext(int *coef, int gain, int mode);               //需重定义参数才能使用 gain:-12.0dB~12.0dB, 步进0.1dB, mode:0(bass), 1(treble)
void eq_coef_cal(u8 index, int *coef, int gain, struct eq_coef_tbl_t *tbl); //index:0~7（8条EQ）, gain:-12dB~12dB
void eq_coef_cal_ext(u8 index, int *coef, int gain, struct eq_coef_tbl_t *tbl); //需重定义参数才能使用 gain:-12.0dB~12.0dB, 步进0.1dB
u8 eq_parse_res(u32 *addr, u32 *len, u32 *coef, u8 *cnt);                   //根据资源文件解析出EQ系数

//aux dnr
void aux_dnr_process(void);
void aux_dnr_init(u8 v_cnt, u16 v_pow, u8 s_cnt, u16 s_pow);
void aux_dnr_detect(void *buf, u16 len);
u16 get_aux_max_power(void);
void aux_analog_channel_select(u8 channel);
void aux_analog_channel_close(u8 channel);
void micaux_analog_out_init(void);

////音频与MIC通道分离; 0：左声道麦，右声道音频；1：左声道音频，右声道麦
void dac_mic_audio_channel_select(u8 channel);

//AT(.com_text) const char sine6[12] = {0x5C, 0xC4, 0xE7, 0xE2, 0xB4, 0x1E, 0xA8, 0x3B, 0xAC, 0x1C, 0xA2, 0xE0};   //默认6个点的正弦波,需要入在公共区 //频率16K/6 = 2.67K
void sine_tone_init(void*sine_tbl, u16 tbl_len, u16 vol); //pcm_buf需要放入公共区，16位单声道 ,播放采样率16K, //vol 声音大小(0~65535)
void sine_tone_play(u16 time); //time 播放时间长度(ms)
void dac_aubufsize_set(u8 flag);   //1  ram x2  //0 ram x1

void cosecant_180_turn(bool en);       //实现dac输出相位180°翻转

typedef enum XDRC_STA_ {
    XDRC_LP_EQ_EN = 0,
    XDRC_HP_EQ_EN,
    XDRC_LP_DRC_EN,
    XDRC_HP_DRC_EN,
    XDRC_ALL_EQ_EN,
    XDRC_ALL_DRC_EN,
}XDRC_STA;
#define XDRC_EN  (BIT(XDRC_LP_EQ_EN) | BIT(XDRC_HP_EQ_EN) | BIT(XDRC_LP_DRC_EN) | BIT(XDRC_HP_DRC_EN))
void xdrc_sta_set(u32 sta);
u32 xdrc_sta_get(void);
bool drc_init_lp(const u32 *coef_res);
bool drc_init_hp(const u32 *coef_res);
void soft_eq_init_lp_hp(const u32 *eq_coef_lp_res, const u32 *eq_coef_hp_res);

#define VCMBUF_ENALBE()     AUANGCON1 |= BIT(29)       //开启VCMBUF电源,该引脚会有1.3V左右的电压输出
#define VCMBUF_DISABLE()    AUANGCON1 &= ~BIT(29)      //关闭VCMBUF电源,关闭后该引脚为阻状态

//spdif数据流接口,库中有 void spdif_pcm_process(s16 *ldata, s16 *rdata) 同名的WEAK函数,在外面重写该函数即可得到或修改SPDIF的数据流
void spdif_dac_bypass_set(u8 bypass);   //1 dac_bypass,spdif收到数据后不推dac   //0 spdif收到数据后正常推dac
u8 spdif_dac_bypass_get(void);          //返回1,当前状态为dac_bypass,spdif收到数据后不推dac   //返回1,当前状态为spdif收到数据后正常推dac

void dac_sw_rm_voice(s16 *ldata, s16 *rdata);  //使用软件消人声算法时,需要调用先karaok_set_voice_rm_type(1, rm_voice_filter_coef),用于初始化滤波器参数rm_voice_filter_coef。
volatile bool ext_rm_voice_en;

void wav_output_tick_start(void);
#endif
